package translater

import (
	"MoSkeleton/framework/core/consts"
	"github.com/BurntSushi/toml"
	"github.com/nicksnyder/go-i18n/v2/i18n"
	"golang.org/x/text/language"
	"log"
	"path/filepath"
	"sync"
)

var defaultLocalizer *i18n.Localizer
var once sync.Once
var bundle *i18n.Bundle

type Translater struct {
	localizer *i18n.Localizer
}

func New() *Translater {
	return NewOnce("./")
}

// workDir参数只有第一次初始化时有效
func NewOnce(workDir string) *Translater {
	once.Do(func() {
		init_I18n(workDir)
	})
	return &Translater{}
}

func NewByRequest(lang, acceptLang string) *Translater {
	return NewByRequest(lang, acceptLang)
}

// workDir参数只有第一次初始化时有效
func NewOnceByRequest(workDir, lang, acceptLang string) *Translater {
	once.Do(func() {
		init_I18n(workDir)
	})
	var translater = &Translater{}
	translater.localizer = i18n.NewLocalizer(bundle, lang, acceptLang)
	return translater
}

func (t *Translater) Translate(key string, args ...interface{}) (string, error) {
	localizer := t.getLocalizer()

	return localizer.Localize(&i18n.LocalizeConfig{
		DefaultMessage: &i18n.Message{
			ID: key,
		},
		TemplateData: args,
	})
}

func (t *Translater) TranslateMust(key string, args ...interface{}) string {
	localizer := t.getLocalizer()
	return localizer.MustLocalize(&i18n.LocalizeConfig{
		DefaultMessage: &i18n.Message{
			ID: key,
		},
		TemplateData: args,
	})
}

func (t *Translater) getLocalizer() *i18n.Localizer {
	var localizer *i18n.Localizer
	if t.localizer != nil {
		localizer = t.localizer
	} else {
		localizer = defaultLocalizer
	}
	return localizer
}

func init_I18n(dir string) {
	//10.全局注册 validator 错误翻译器
	if err := InitTrans(ChangeLangToLocale(Profile.GetLanguage())); err != nil {
		log.Fatal(consts.ErrorsValidatorTransInitFail + err.Error())
	}
	bundle = i18n.NewBundle(language.SimplifiedChinese)
	bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)

	for _, file := range scanTomlFiles(dir) {
		bundle.LoadMessageFile(file)
	}
	defaultLocalizer = i18n.NewLocalizer(bundle, Profile.GetLanguage())
}

func scanTomlFiles(dir string) []string {
	var finalFile = filepath.Join(dir, consts.I18nPath, "active.*.toml")
	matches, err := filepath.Glob(finalFile)

	if err != nil {
		panic("search i18n toml files fail")
	}
	return matches
}
